import { mysql } from 'app/src-ssr/db/connect';
import config from 'app/src-ssr/db/config';

const Table = {};
const Dict = {
  bigint: 'Number',
  int: 'Number',
  double: 'Number',
  decimal: 'Number',
  float: 'Number'
};

export const init = async () => {
  const [rows, fields] = await mysql.query(`SELECT
    CONCAT( '{', GROUP_CONCAT( concat( '"', COLUMN_NAME, '"', ':"', DATA_TYPE, '"' ) ), '}' ) field,
    TABLE_NAME name
    FROM
    information_schema.COLUMNS
    WHERE
    TABLE_SCHEMA = ? AND EXTRA<>'VIRTUAL GENERATED'
    GROUP BY
    TABLE_NAME;`,
  [config.database]
  );

  rows.forEach(item => {
    Table[item.name] = JSON.parse(
      // eslint-disable-next-line no-useless-escape
      item.field.replace(/\:"([^"]*)"/g, function (match, p1) {
        return `:"${Dict[p1] || ''}"`;
      })
    );
  });
  global._tableStructure = Object.freeze(Table);
};

const toString = Object.prototype.toString;

function isNil (p) {
  return p === undefined || p === null;
}

/**
 * 是否为数字或者由数字组成的字符串
 * @param {*} p
 */
function isLikeNumber (p) {
  if (typeof p === 'number') {
    if (Number.isNaN(p)) {
      return false;
    }
  } else if (typeof p === 'string') {
    if (p.trim() === '') {
      return false;
    } else if (Number.isNaN(Number(p))) {
      return false;
    }
  } else {
    return false;
  }

  return true;
}
/**
 * 返回所有符合表字段类型规则的字段组成的新对象
 * @param {String} tableName
 * @param {Object} record
 * @param {Array<String>} [ignoreType] 忽略的类型，如果数据为此中类型则跳过检测，通过Object.prototype.toString来判断
 * @return {Object}
 */
export const filterField = function (tableName, record, ignoreType = []) {
  const table = Table[tableName];

  if (!table) {
    console.error('undefined table:', tableName);
    return [];
  }

  const cleanData = [];
  let dataset = [];
  if (record === undefined) return record;

  if (Object.prototype.toString.call(record) === '[object Object]') {
    dataset = [record];
  } else {
    dataset = record;
  }

  for (const row of dataset) {
    const data = {};
    Object.keys(row).forEach(key => {
      if (key in table) {
        if (ignoreType.includes(toString.call(row[key]).slice(8, -1).toLowerCase())) {
          data[key] = row[key];
          return;
        }
        let fieldValue = row[key];
        // if (isNil(row[key]) || (table[key] === 'Number' && !isLikeNumber(row[key]))) {
        if (table[key] === 'Number' && row[key] !== null && !isLikeNumber(row[key])) { // 数值型的，null不过滤，其它不像数字的过滤
          if (row[key] === '') { // 数值型为空时，设置为null
            fieldValue = null;
          } else {
            // 如果表中字段为int等类型，则检测值是否为数字类型
            return;
          }
        }

        data[key] = fieldValue;
      }
    });
    cleanData.push(data);
  }
  // 把前后的空格给去掉
  cleanData.forEach(row => {
    for (const key in row) {
      if (typeof row[key] === 'string') {
        row[key] = row[key].trim();
      }
    }
  });

  if (Object.prototype.toString.call(record) === '[object Object]') {
    return cleanData[0];
  } else {
    return cleanData;
  }
};

/** 查找有指定字段的表
 * @param {string} field 字段名
 * @return {array} 包含该字段的所有表名
 */
export const findTablesByField = (field) => {
  const tables = [];
  Object.keys(Table).forEach(table => {
    Object.keys(Table[table]).filter(v => v == field).length > 0 && tables.push(table);
  });
  return tables;
};

export default { init, filterField, findTablesByField }
